2.2. Models
In one glance
- You will: Explain provider selection, credentials, timeouts, and the optional local model path.
- You need: A first agent and familiarity with the repository-root .env.
- Time: about 15 minutes, reference.
Why are the provider and model explicit?
The provider selects the client protocol; the model selects the inference implementation.
entrypoint: AgentEntrypoint = AgentEntrypoint.AGENT
model_provider: ModelProvider = ModelProvider.GEMINI
# Keep the learner and gateway model aligned with the qualified platform pair.
model: str = Field(default="gemini-3.5-flash", min_length=1)
# ``openai-compatible`` describes the ADK client contract, not the
# deployment topology. These defaults support the optional Ollama path;
# Part II instead points the adapter at agentgateway.
openai_base_url: str | None = Field(
default="http://127.0.0.1:11434/v1",
validation_alias=AliasChoices("OPENAI_BASE_URL"),
)
openai_api_key: SecretStr | None = Field(
default=SecretStr("local-ollama"),
validation_alias=AliasChoices("OPENAI_API_KEY"),
)
# Default Gemini path: an AI Studio API key; optional Enterprise/Vertex via ADC
# with an explicit project and location.
google_api_key: SecretStr | None = Field(
default=None,
validation_alias=AliasChoices("GOOGLE_API_KEY"),
)
google_genai_use_enterprise: bool = Field(
default=False,
validation_alias=AliasChoices("GOOGLE_GENAI_USE_ENTERPRISE"),
)
google_cloud_project: str | None = Field(
default=None,
validation_alias=AliasChoices("GOOGLE_CLOUD_PROJECT"),
)
google_cloud_location: str | None = Field(
default=None,
validation_alias=AliasChoices("GOOGLE_CLOUD_LOCATION"),
)
The default is native Gemini with an API key. The optional OpenAI-compatible adapter connects to Ollama or agentgateway. openai-compatible does not mean an OpenAI-hosted model: it names the transport contract.
How does the application construct its model?
One factory constructs the configured ADK client without changing the domain tools.
def build_model() -> str | BaseLlm:
"""Return the configured ADK model implementation.
The default Gemini mode uses ADK's native integration. The alternate mode
uses ADK's OSS OpenAI-compatible client; ``OPENAI_BASE_URL`` chooses direct
Ollama or an agentgateway route without changing application code. When
``AGENT_MODEL_FALLBACK`` names a second model, ADK's ``FallbackModel`` tries
it on the same provider after a retriable 429/5xx from the primary, and only
before the primary has produced any output (Chapter 2.2).
"""
settings.require_model_credentials()
primary = _build_single(settings.model)
if settings.model_fallback is None:
return primary
return FallbackModel(models=[primary, _build_single(settings.model_fallback)])
A missing Gemini key fails when a model is constructed or config:check runs. Read-only tools can import their settings without model credentials. Invalid combinations, including simultaneous API-key and enterprise authentication, still fail configuration validation.
The module does not start an inference server. Gemini requires network access and quota; Ollama requires its separately running server and downloaded model.
Which settings change at each boundary?
Each transition has an explicit configuration change and a separate validation step.
| Path | Provider | Model endpoint | Credential |
|---|---|---|---|
| Laptop default | gemini |
Native Gemini API | GOOGLE_API_KEY |
| Host gateway | openai-compatible |
http://127.0.0.1:4000/v1 |
Non-secret local caller marker; gateway owns upstream key |
| Kubernetes gateway | openai-compatible |
Cluster-local agentgateway endpoint | Gateway caller Secret; separate Gemini provider Secret |
| Optional local model | openai-compatible |
http://127.0.0.1:11434/v1 |
Non-secret local-ollama marker |
The platform transport is a real change. Re-run tool-result, approval, and evaluation cases rather than assuming a successful HTTP response proves equivalence.
How are retries and timeouts bounded?
The application owns the model deadline and retry count.
Both adapters use AGENT_MODEL_TIMEOUT_S and AGENT_MAX_RETRIES; Gemini also maps the configured backoff. A retried inference request may repeat model work and cost. Guarded writes remain outside automatic retry behavior.
AGENT_MODEL_FALLBACK is an advanced same-provider option, disabled by default. It does not turn Gemini failures into automatic local inference. Switching the learner to Ollama is an explicit configuration choice.
When set, build_model() wraps both models in ADK's experimental FallbackModel. It moves to the second model only after a 429 or 5xx from the first, and only before the first has produced any output. A 4xx request error, a 408 timeout that may already have been processed and billed, or a failure mid-stream reaches the caller unchanged. Each model's own retry policy runs first, so one failure is never retried twice over. Evaluations refuse to run with a fallback set, because every answer would be attributed to the primary.
What proves this page worked?
mise run config:check
You are done when:
- You can identify your provider, model, endpoint, and credential owner.
- Configuration passes with credentials masked.
- You understand which changes require a new live evaluation.
Continue to 2.3. Instructions when you can explain how the model is selected.